home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Programmer Disk
/
The Programmer Disk (Microforum).iso
/
xpro
/
c3
/
pro24
/
noteoff.c
< prev
next >
Wrap
Text File
|
1986-08-06
|
5KB
|
158 lines
/* noteoff.c -- this module keeps track of pending note offs for adagio */
/*****************************************************************************
* Change Log
* Date | Change
*-----------+-----------------------------------------------------------------
* 31-Dec-85 | Created changelog
* 31-Dec-85 | Add c:\ to include directives
* 1-Jan-86 | Declare getmem char * for lint consistency
* 21-Jan-86 | note_offs can now turn off more than one note per call
*****************************************************************************/
#include "cext.h"
#include "stdio.h"
#include "ctype.h"
#include "adagio.h"
/* off_type is a structure containing note-off information */
typedef struct off_struct {
long when;
int voice;
int pitch;
struct off_struct *next;
} *off_type;
private off_type free_off; /* free list of off_type structures */
private off_type off_events = NULL; /* active list */
extern char * getmem();
/****************************************************************************
* Routines declared in this module
****************************************************************************/
boolean note_offs();
private off_type off_alloc();
private void off_free();
void off_init();
void off_schedule();
/****************************************************************************
* note_offs
* Inputs:
* long time: the current time
* Outputs:
* return true if off list has more notes
* Effect: turn off notes if it is time
* Assumes:
* Implementation:
* Find scheduled note off events in off_events, compare with time
****************************************************************************/
boolean note_offs(time)
long time;
{
off_type temp;
while (off_events != NULL && off_events->when <= time) {
midi_note((off_events->voice) + 1, off_events->pitch, 0);
temp = off_events;
off_events = off_events->next;
off_free(temp);
}
return (off_events != NULL);
}
/****************************************************************************
* off_alloc
* Outputs:
* returns off_type: an allocated note off structure
* Effect:
* allocates a structure using getmem
****************************************************************************/
private off_type off_alloc()
{
return (off_type) getmem(sizeof(struct off_struct));
}
/****************************************************************************
* off_free
* Inputs:
* off_type off: a structure to deallocate
* Effect:
* returns off to freelist
****************************************************************************/
private void off_free(off)
off_type off;
{
off->next = free_off;
free_off = off;
}
/****************************************************************************
* off_init
* Effect: initialize this module
* Assumes:
* only called once, otherwise storage is leaked
****************************************************************************/
void off_init()
{
int i;
for (i = 0; i < 50; i++) off_free(off_alloc());
}
/****************************************************************************
* off_schedule
* Inputs:
* long offtime: time to turn note off
* int voice: the midi channel
* int pitch: the pitch
* Effect:
* schedules a note to be turned off
* Assumes:
* note_offs will be called frequently to actually turn off notes
****************************************************************************/
void off_schedule(offtime, voice, pitch)
long offtime;
int voice, pitch;
{
off_type off, ptr, prv;
/* allocate off */
if ((off = free_off) == NULL) {
off = off_alloc();
} else free_off = off->next;
if (off == NULL) {
fprintf(stderr, "out of space for note off events");
musicterm();
exit(1);
}
off->when = offtime;
off->voice = voice;
off->pitch = pitch;
/* insert into list of off events */
ptr = off_events;
if (ptr == NULL || offtime <= ptr->when) {
off->next = ptr;
off_events = off;
} else {
while (ptr != NULL && offtime > ptr->when) {
prv = ptr;
ptr = ptr->next;
}
prv->next = off;
off->next = ptr;
}
/*
* printf("off_schedule(%ld, %d, %d): \n", offtime, voice, pitch);
* for (ptr = off_events; ptr != NULL; ptr = ptr->next) {
* printf(" %ld: %d, %d\n", ptr->when, ptr->voice, ptr->pitch);
* }
*/
}